#include <stdio.h>
#include <gmp.h>

int main(){

   mpf_set_default_prec(35000000);

   mpf_t a_n;         //An
   mpf_t a_n1;        //An+1
   mpf_t b_n;         //Bn
   mpf_t b_n1;        //Bn+1
   mpf_t t_n;         //Tn
   mpf_t t_n1;        //Tn+1
   mpf_t p_n;         //Pn
   mpf_t p_n1;        //Pn+1
   mpf_t pi;          //Pi
   mpf_t aux, aux2, aux3, aux4, aux5, aux6, aux7, aux8;    //variaveis auxiliares
   int k;

   //inicializacao das variaveis da biblioteca GMP
   mpf_init(a_n);
   mpf_init(a_n1);
   mpf_init(b_n);
   mpf_init(b_n1);
   mpf_init(t_n);
   mpf_init(t_n1);
   mpf_init(p_n);
   mpf_init(p_n1);
   mpf_init(pi);
   mpf_init(aux);
   mpf_init(aux2);
   mpf_init(aux3);
   mpf_init(aux4);
   mpf_init(aux5);
   mpf_init(aux6);
   mpf_init(aux7);
   mpf_init(aux8);

   //valor inicial das variaveis
    mpf_set_ui(a_n, 1);
    mpf_sqrt_ui(b_n,2);
    mpf_ui_div(b_n, 1, b_n);
    mpf_set_ui(t_n, 1);
    mpf_div_ui(t_n,t_n,4);
    mpf_set_ui(p_n, 1);

   //Gauss-Legendre
   for(k = 0; k <= 22; k++){

        //calculo de An+1
        mpf_add(aux, a_n, b_n);
        mpf_div_ui(a_n1, aux, 2);

        //calculo de Bn+1
        mpf_mul(aux2, a_n, b_n);
        mpf_sqrt(b_n1, aux2);

        //calculo de Tn+1
        mpf_sub(aux3, a_n, a_n1);
        mpf_pow_ui(aux4, aux3, 2);
        mpf_mul(aux5, p_n, aux4);
        mpf_sub(t_n1, t_n, aux5);

        //calculo de Pn+1
        mpf_mul_ui(p_n1, p_n, 2);

        //atualiza variaveis
        mpf_set(a_n, a_n1);
        mpf_set(b_n, b_n1);
        mpf_set(t_n, t_n1);
        mpf_set(p_n, p_n1);

        //calculo do pi
        mpf_add(aux6, a_n, b_n);
        mpf_pow_ui(aux7, aux6, 2);
        mpf_mul_ui(aux8, t_n, 4);
        mpf_div(pi, aux7, aux8);

        //imprime valor do pi
        //printf("k: %d\n", k);
        //gmp_printf("Pi %.1000000000Ff\n", pi);
   }

   mpf_clear(a_n);
   mpf_clear(a_n1);
   mpf_clear(b_n);
   mpf_clear(b_n1);
   mpf_clear(t_n);
   mpf_clear(t_n1);
   mpf_clear(p_n);
   mpf_clear(p_n1);
   mpf_clear(pi);
   mpf_clear(aux);
   mpf_clear(aux2);
   mpf_clear(aux3);
   mpf_clear(aux4);
   mpf_clear(aux5);
   mpf_clear(aux6);
   mpf_clear(aux7);
   mpf_clear(aux8);

   return(0);
}
